//
//  CoreDataBase.swift
//  Swift-app开发基础架构
//
//  Created by pro on 2017/8/17.
//  Copyright © 2017年 com.itboye. All rights reserved.
//

import UIKit

import FMDB
// FIXME: 数据库数据类
class DBModel: NSObject {
    

    var id          : Int       = 0
    var key         : String    = ""
    var value       : Data?     = nil
    var type        : String    = ""
    var updateTime  : Int       = 0
    var expireTime  : Int       = 0
    
    override init() {
        super.init()
    }
    
    init(id         : Int,
         key        : String,
         value      : Data?,
         type       : String,
         updateTime : Int,
         expireTime : Int) {
        
        self.id = id
        self.key = key
        self.value = value
        self.type = type
        self.updateTime = updateTime
        self.expireTime = expireTime
    }

}

// FIXME: 数据库操作类
class KZDataBase: NSObject {
    
    static var _dbQueue: FMDatabaseQueue! = nil
    
    static let dbBundle: Bundle? = Bundle.main
    
    static func openDB() {
        
        // 设置想要存储数据库db文件的位置
        let doc = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        let fileName = doc.appending("/itboye_cache.db")
        // print(fileName)
        
        // 把数据库文件从工程文件及中赋值到Documents中
        if !FileManager.default.fileExists(atPath: fileName) {
            let dbPath = dbBundle?.path(forResource: "itboye", ofType: "db")
            // 下面2种方式相同
            if ((try? FileManager.default.copyItem(atPath: dbPath!, toPath: fileName)) != nil) {
                print("拷贝成功")
            } else {
                print("拷贝失败")
                return
            }
            
//             do {
//                try FileManager.default.copyItem(atPath: dbPath!, toPath: fileName)
//                print("拷贝成功")
//             } catch  {
//                print("拷贝失败")
//                return
//             }
        }
       
        
        // 创建数据库，并加入到队列中，此时已经默认打开了数据库，无须手动打开，只需要从队列中去取数据库即可
        if (_dbQueue == nil) {
            _dbQueue = FMDatabaseQueue(path: fileName)
        }
    }
    
    // 查询（全部）
    static func query() -> [DBModel] {
        
        // 打开数据库
        self.openDB()
        
        // 创建数组变量，用于存储返回值
        var list = [DBModel]()
        
        // 开始查询
        _dbQueue.inDatabase { (db) in
            
            // 开启事务:事务对于数据库的作用是对数据的一系列操作，要么全部成功，要么全部失败，防止中间状态的出现，以确保数据库中的数据始终处于正确及和谐状态。
            db.beginTransaction()

            let set: FMResultSet? = try? db.executeQuery("SELECT * FROM common_cache", values: [])
            if set != nil {
                while set!.next() {
                    let model = DBModel(id: set!.long(forColumn: "id"),
                                        key: set!.string(forColumn: "key")!,
                                        value: set!.data(forColumn: "value"),
                                        type: set!.string(forColumn: "type")!,
                                        updateTime: set!.long(forColumn: "update_time"),
                                        expireTime: set!.long(forColumn: "expire_time"))
                    list.append(model)
                }
                set?.close();
            }
            db.commit()
        }
        return list
    }

    static func query(key: String) -> DBModel? {
        
        self.openDB()
        
        var model: DBModel? = nil
        
        _dbQueue.inDatabase { (db) in
            
            db.beginTransaction()
            
            // 根据键名查找，最多只会有一条
            let set: FMResultSet? = try? db.executeQuery("SELECT * FROM common_cache where key = ?", values: [key])
            // 在我们知道最多只有1条的情况下，可以直接这样判断
            if set != nil && set?.next() == true {
                model = DBModel(id: set!.long(forColumn: "id"),
                                key: set!.string(forColumn: "key")!,
                                value: set!.data(forColumn: "value"),
                                type: set!.string(forColumn: "type")!,
                                updateTime: set!.long(forColumn: "update_time"),
                                expireTime: set!.long(forColumn: "expire_time"))
                
            }
            set?.close()
            db.commit()
        }

        return model
    }
    
    static func setItemWithKey(key: String,
                               value: Data,
                               type: String,
                               updateTime: Int,
                               expireTime: Int) {
    
        openDB()
        
        _dbQueue.inDatabase { (db) in
            
            let set: FMResultSet? = try? db.executeQuery("SELECT * FROM common_cache where key = ?", values: [key])
            if set != nil {
                // 键名已存在
                if set!.next() {
                    
                    if (try? db.executeUpdate("update common_cache set value = ?, type = ?, update_time = ?, expire_time = ? where key = ?", values: [value, type, updateTime, expireTime, key])) != nil {
                        // 覆盖成功
                        print("覆盖成功")
                    } else {
                        print("覆盖失败")
                    }
                } else {

                    if (try? db.executeUpdate("insert into common_cache (key, value, type, update_time, expire_time) values(?,?,?,?,?)", values: [key, value, type, updateTime, expireTime])) != nil {
                        // 添加成功
                        print("添加成功")
                    } else {
                        print("添加失败")
                    }
                }
                set?.close()
            }
        }
    }
    
    
    static func deleteItem(key: String) {
        
        openDB()
        
        _dbQueue.inDatabase { (db) in
            
            if ((try? db.executeUpdate("delete from common_cache where key = ?", values: [key])) != nil) {
                // 删除成功
                print("删除成功")
            } else {
                print("删除失败")
            }
        }
    }
}
